package com.citycloud.ccuap.tc.yq.dimensioncls;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.citycloud.ccuap.commons.json.CheckedTreeNode;
import com.citycloud.ccuap.framework.service.mybatis.MybatisServiceImpl;
import com.citycloud.ccuap.tc.yq.entity.MetaField;
import com.citycloud.ccuap.tc.yq.entity.MetaTable;
import com.citycloud.ccuap.tc.yq.entity.MetaTableCate;
import com.citycloud.ccuap.tc.yq.entity.SysDimensionCls;
import com.citycloud.ccuap.tc.yq.entity.SysDimensionDs;
import com.citycloud.ccuap.tc.yq.entity.SysDimensionField;
import com.citycloud.ccuap.tc.yq.entity.SysDimensionTable;
import com.citycloud.ccuap.tc.yq.repository.MetaFieldRepository;
import com.citycloud.ccuap.tc.yq.repository.MetaTableCateRepository;
import com.citycloud.ccuap.tc.yq.repository.MetaTableRepository;
import com.citycloud.ccuap.tc.yq.repository.SysDimensionClsRepository;
import com.citycloud.ccuap.tc.yq.repository.SysDimensionDsRepository;
import com.citycloud.ccuap.tc.yq.repository.SysDimensionFieldRepository;
import com.citycloud.ccuap.tc.yq.repository.SysDimensionTableRepository;

/**
 * 数据维度-对分类业务处理实现
 * @author sufeng
 *
 */
@Service
public class SysDimensionClsService extends MybatisServiceImpl<SysDimensionClsRepository, SysDimensionCls, String> implements ISysDimensionClsService {

    @Autowired
    private SysDimensionClsRepository sysDimensionClsRepository;

    @Autowired
    private MetaTableCateRepository metaTableCateRepository;

    @Autowired
    private SysDimensionTableRepository secDimensionTableRepository;

    @Autowired
    private MetaTableRepository metaTableRepository;

    @Autowired
    private SysDimensionFieldRepository secDimensionFieldRepository;
    
    @Autowired
    private SysDimensionDsRepository sysDimensionDsRepository;
    
    @Autowired
    private MetaFieldRepository metaFieldRepository;


    @Override
    @Cacheable(cacheNames="datagroupCache", key = "#datagroupId")
    public List<CheckedTreeNode> findNextChildNodeTree(String datagroupId){
    	List<CheckedTreeNode> treeList = new ArrayList<>();
        List<String> dsDimensionList = new ArrayList<String>();
        List<String> secDimensionList = new ArrayList<String>();
        List<String> tableSecDimensionList=new ArrayList<String>();
        List<String> fieldSecDimensionList=new ArrayList<String>();
        if(StringUtils.isNotEmpty(datagroupId)) {
        	dsDimensionList=(List<String>) selectListBySimple("select ds_id from sys_dimension_ds where  datagroup_id='"+datagroupId+"'");
        	secDimensionList = (List<String>) selectListBySimple("select cat_id from sys_dimension_cls where  datagroup_id='"+datagroupId+"'");
        	tableSecDimensionList =  (List<String>) selectListBySimple("select table_id from sys_dimension_table where datagroup_id='"+datagroupId+"'");;
        	fieldSecDimensionList =  (List<String>) selectListBySimple("select field_id from sys_dimension_field where  datagroup_id='"+datagroupId+"'");
        }
       List<Map<String,Object>> list= selectList("select * from cs_t_datasource_view where 1=1", true);
        for(int i=0;i<list.size();i++) {
        	Map<String,Object> map=list.get(i);
        	CheckedTreeNode treeNode = new CheckedTreeNode();
        	if(dsDimensionList.contains(map.get("objId"))) {
        		treeNode.setChecked(true);
        	}else{
        		treeNode.setChecked(false);
        	}
        	treeNode.setId(map.get("objId").toString());
			treeNode.setText(map.get("dbName").toString());
			treeNode.setExpanded(false);
			List<MetaTableCate> metas = metaTableCateRepository.findByIsDeletedAndSpaceIdOrderByCreatedate(false,map.get("objId").toString());
			if(metas.size()==0) {
				treeNode.setLeaf(true);
			}else {
				treeNode.setLeaf(false);
			}
			treeNode.setType("ds");
			treeList.add(getCateNextChildNodeTreeNew(treeNode,datagroupId, null,metas,secDimensionList,tableSecDimensionList,fieldSecDimensionList));
        }
        return treeList;
    };

    
    private CheckedTreeNode getCateNextChildNodeTreeNew(CheckedTreeNode treeNode,String datagroupId, String pid,List<MetaTableCate> metas, List<String> secDimensionList, List<String> tableSecDimensionList, List<String> fieldSecDimensionList){
        treeNode.setChildren(secDimensionListToTree(metas,secDimensionList,datagroupId,tableSecDimensionList,fieldSecDimensionList));
        return treeNode;
    }
    
    private List<CheckedTreeNode> secDimensionListToTree(List<MetaTableCate> metas,List<String> secDimensionList,String datagroupId, List<String> tableSecDimensionList, List<String> fieldSecDimensionList) {
		List<CheckedTreeNode> treeList = new ArrayList<>();
		for (MetaTableCate meta : metas) {
			if (StringUtils.isEmpty(meta.getPid())) {
				CheckedTreeNode treeNode = new CheckedTreeNode();
				treeNode.setId(meta.getObjId());
				treeNode.setText(meta.getCateName());
				treeNode.setExpanded(false);
				treeNode.setLeaf(false);
				treeNode.setType("cate");
				if(secDimensionList.contains(meta.getObjId())){
					treeNode.setChecked(true);
				}else{
					treeNode.setChecked(false);
				}
				treeList.add(findDimensionChildren(treeNode,metas, secDimensionList,datagroupId,tableSecDimensionList,fieldSecDimensionList));
			}
		}
		return treeList;
	}
    
    private  List<CheckedTreeNode> getTableNextChildNodeTreeNew(String datagroupId, List<MetaTable>  metables, List<String> tableSecDimensionList, List<String> fieldSecDimensionList){
        List<CheckedTreeNode> nodes = new ArrayList<CheckedTreeNode>();

        for(MetaTable meta:metables){
            CheckedTreeNode node = new CheckedTreeNode();
            node.setId(meta.getObjId());
            node.setText(meta.getTableCname());
            node.setExpanded(false);
            List<MetaField> metas =  metaFieldRepository.findByTableIdAndIsDeleted(meta.getObjId(),false);
            if(metas.size()>0) {
            	node.setLeaf(false);
            }else {
            	node.setLeaf(true);
            }
            node.setType("table");

            if(tableSecDimensionList.contains(meta.getObjId())){
                node.setChecked(true);
            }else{
                node.setChecked(false);
            }
            node.setChildren(getFieldNextChildNodeTreeNew(datagroupId,metas,fieldSecDimensionList));
            nodes.add(node);
        }
        return nodes;
    }
    
    private List<CheckedTreeNode> getFieldNextChildNodeTreeNew(String datagroupId, List<MetaField> metas, List<String> fieldSecDimensionList){
        List<CheckedTreeNode> nodes = new ArrayList<CheckedTreeNode>();
        for(MetaField meta:metas){
            CheckedTreeNode node = new CheckedTreeNode();
            node.setId(meta.getObjId());
            node.setText(meta.getCname());
            node.setExpanded(true);
            node.setLeaf(true);
            node.setType("field");
            if(fieldSecDimensionList.contains(meta.getObjId())){
                node.setChecked(true);
            }else{
                node.setChecked(false);
            }
            nodes.add(node);
        }
        return nodes;
    }
    
    private CheckedTreeNode findDimensionChildren(CheckedTreeNode parent, List<MetaTableCate> metas,List<String> secDimensionList,String datagroupId, List<String> tableSecDimensionList, List<String> fieldSecDimensionList) {
		for (MetaTableCate meta : metas) {
			if (parent.getId().equals(meta.getPid())) {
				CheckedTreeNode treeNode = new CheckedTreeNode();
				treeNode.setId(meta.getObjId());
				treeNode.setText(meta.getCateName());
				treeNode.setExpanded(false);
				List<MetaTable>  metables= metaTableRepository.findByCateIdAndIsDeleted(meta.getObjId(),false);
				 if(metables.size()>0) {
					 treeNode.setLeaf(false); 
				 }else {
					 treeNode.setLeaf(true); 
				 }
				
				treeNode.setType("cate");
				if(secDimensionList.contains(meta.getObjId())){
				    treeNode.setChecked(true);
		        }else{
	            	treeNode.setChecked(false);
		        }
				treeNode.setChildren(getTableNextChildNodeTreeNew(datagroupId,metables, tableSecDimensionList, fieldSecDimensionList));
				
				parent.addNode(findDimensionChildren(treeNode, metas,secDimensionList,datagroupId, tableSecDimensionList, fieldSecDimensionList));
			}
		}
		return parent;
	}
    


    @Override
    public Map<String,List<String>> getLinkedDimensions(String datagroupId){
        Map<String,List<String>> map = new HashMap<String,List<String>>(8);
        List<SysDimensionCls>  cates = sysDimensionClsRepository.findByDatagroupId(datagroupId);
        List<SysDimensionTable>  tables =  secDimensionTableRepository.findByDatagroupId(datagroupId);
        List<SysDimensionField>  fields =  secDimensionFieldRepository.findByDatagroupId(datagroupId);
        List<SysDimensionDs>  ds =  sysDimensionDsRepository.findByDatagroupId(datagroupId);

        map.put("dimensionCateId",cates.stream().map(t -> t.getCateId()).collect(Collectors.toList()));
        map.put("dimensionTableId",tables.stream().map(t -> t.getTableId()).collect(Collectors.toList()));
        map.put("dimensionFieldId",fields.stream().map(t -> t.getFieldId()).collect(Collectors.toList()));
        map.put("dimensionDsId",ds.stream().map(t -> t.getDsId()).collect(Collectors.toList()));
        return map;
    }

}